package com.itheima.servetdemo1.service;

import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import java.util.*;
import java.io.*;

/**
 * 随机点名服务类
 * 负责处理点名相关的业务逻辑
 */
@Service
public class RollCallService {
    // 使用静态Map存储学生数据
    private static Map<String, String> studentMap = new HashMap<>();
    private static Map<String, String> calledStudentsMap = new HashMap<>();
    private final Random random = new Random();
    
    // 添加新的成员变量，用于存储每个学生可以被抽中的最大次数和当前被抽中的次数
    private static int maxCallTimes = 1; // 默认每个学生只能被抽中一次
    private static Map<String, Integer> studentCallCount = new HashMap<>();
    
    // 添加学生个人最大点名次数的Map
    private static Map<String, Integer> studentMaxCallTimes = new HashMap<>();
    
    // 文件路径常量
    private static final String SAVE_FILE_PATH = "students_state.txt";
    private static final String CALL_COUNT_FILE_PATH = "students_call_count.txt";
    
    @PostConstruct
    public void init() {
        // 尝试从文件加载已保存的状态
        loadStateFromFile();
        loadCallCountFromFile();
        
        // 如果没有数据，则初始化默认学生
        if (studentMap.isEmpty() && calledStudentsMap.isEmpty()) {
            initialize();
        }
    }
    
    private void initialize() {
        // 添加默认的学生数据

// 第一组
        studentMap.put("王硕", "第一组");
        studentMap.put("苗俊豪", "第一组");
        studentMap.put("王昊强", "第一组");
        studentMap.put("李嘉明", "第一组");
        studentMap.put("郑万发", "第一组");
        studentMap.put("罗相杰", "第一组");
        studentMap.put("张博文", "第一组");
        studentMap.put("孙金辉", "第一组");
        studentMap.put("张弼儒", "第一组");
        studentMap.put("赵文溪", "第一组");

// 第二组
        studentMap.put("陈文阳", "第二组");
        studentMap.put("高屹森", "第二组");
        studentMap.put("夏启航", "第二组");
        studentMap.put("薛帅聪", "第二组");
        studentMap.put("皇事成", "第二组");
        studentMap.put("化江涛", "第二组");
        studentMap.put("李乐", "第二组");
        studentMap.put("陈玺锦", "第二组");
        studentMap.put("李岩奇", "第二组");
        studentMap.put("王立豪", "第二组");

// 第三组
        studentMap.put("刘力豪", "第三组");
        studentMap.put("王润泽", "第三组");
        studentMap.put("李行", "第三组");
        studentMap.put("任玉琦", "第三组");
        studentMap.put("段辰奇", "第三组");
        studentMap.put("宋雨轩", "第三组");
        studentMap.put("曹今朝", "第三组");
        studentMap.put("卢佳豪", "第三组");
        studentMap.put("吴朝卿", "第三组");
        studentMap.put("李亚轩", "第三组");

// 第四组
        studentMap.put("尤锐", "第四组");
        studentMap.put("魏宇翔", "第四组");
        studentMap.put("栗展博", "第四组");
        studentMap.put("张易昱", "第四组");
        studentMap.put("刘松林", "第四组");
        studentMap.put("朱星宇", "第四组");
        studentMap.put("李雪枫", "第四组");
        studentMap.put("朱昱嘉", "第四组");
        studentMap.put("宋俊衡", "第四组");
        studentMap.put("董岑", "第四组");

// 第五组
        studentMap.put("刘林豪", "第五组");
        studentMap.put("夏永悦", "第五组");
        studentMap.put("王文豪", "第五组");
        studentMap.put("张金泽", "第五组");
        studentMap.put("王鑫冉", "第五组");
        studentMap.put("孙苗苗", "第五组");
        studentMap.put("李曼曼", "第五组");
        studentMap.put("王优雅", "第五组");
        studentMap.put("林钇兵", "第五组");
        studentMap.put("陈靖", "第五组");

// 第六组
        studentMap.put("王俊哲", "第六组");
        studentMap.put("陈熙", "第六组");
        studentMap.put("孙培松", "第六组");
        studentMap.put("谭雲灿", "第六组");
        studentMap.put("刘朝阳", "第六组");
        studentMap.put("赵忠博", "第六组");
        studentMap.put("曹文沛", "第六组");
        studentMap.put("朱永昌", "第六组");
        studentMap.put("王文乐", "第六组");
        studentMap.put("谷新航", "第六组");

// 第七组
        studentMap.put("孙锦涛", "第七组");
        studentMap.put("李京洋", "第七组");
        studentMap.put("肖华", "第七组");
        studentMap.put("毛成琦", "第七组");
        studentMap.put("鹿帅", "第七组");
        studentMap.put("华琳", "第七组");
        studentMap.put("杨志鹏", "第七组");
        studentMap.put("王策", "第七组");
        studentMap.put("孙号蔺", "第七组");
        studentMap.put("张佳豪", "第七组");

// 第八组
        studentMap.put("王昱森", "第八组");
        studentMap.put("夏浩洋", "第八组");
        studentMap.put("高晨", "第八组");
        studentMap.put("刘翔", "第八组");
        studentMap.put("韩思源", "第八组");
        studentMap.put("高帅甲", "第八组");
        studentMap.put("马靖杰", "第八组");
        studentMap.put("万启宝", "第八组");
        studentMap.put("金渊博", "第八组");
        studentMap.put("李贺", "第八组");

// 第九组
        studentMap.put("银星宇", "第九组");
        studentMap.put("左建亮", "第九组");
        studentMap.put("王颂", "第九组");
        studentMap.put("王子卿", "第九组");
        studentMap.put("刘思远", "第九组");
        studentMap.put("石万", "第九组");
        studentMap.put("陶智源", "第九组");
        studentMap.put("时若晨", "第九组");
        studentMap.put("王俊骅", "第九组");
        studentMap.put("闫智远", "第九组");

// 第十组
        studentMap.put("张家宁", "第十组");
        studentMap.put("吉康", "第十组");
        studentMap.put("贾庆能", "第十组");
        studentMap.put("张朝亮", "第十组");
        studentMap.put("荆艳慧", "第十组");
        studentMap.put("张淮月", "第十组");
        studentMap.put("常薇", "第十组");
        studentMap.put("曹硕寒", "第十组");
        studentMap.put("郭书含", "第十组");
        studentMap.put("马丁丁", "第十组");

// 第十一组
        studentMap.put("朱佟俣", "第十一组");
        studentMap.put("王程锦", "第十一组");
        studentMap.put("徐路越", "第十一组");
        studentMap.put("王栋", "第十一组");
        studentMap.put("高明泽", "第十一组");
        studentMap.put("张保潼", "第十一组");
        studentMap.put("梁仲毅", "第十一组");
        studentMap.put("师旭光", "第十一组");
        studentMap.put("袁昂", "第十一组");
        studentMap.put("郭蒙蒙", "第十一组");


        // 可以继续添加更多学生...
        
        // 保存初始状态到文件
        saveStateToFile();
    }
    
    /**
     * 添加设置最大抽中次数的方法
     * @param times 新的最大抽中次数
     */
    public void setMaxCallTimes(int times) {
        if (times > 0) {
            maxCallTimes = times;
            saveCallCountToFile();
        }
    }
    
    /**
     * 获取最大抽中次数
     */
    public int getMaxCallTimes() {
        return maxCallTimes;
    }
    
    /**
     * 设置指定学生的最大点名次数
     * @param studentName 学生姓名
     * @param times 最大点名次数
     *
     */
    public boolean setStudentMaxCallTimes(String studentName, int times) {
        if (times <= 0 || !studentMap.containsKey(studentName)) {
            return false;
        }
        studentMaxCallTimes.put(studentName, times);
        saveCallCountToFile();
        return true;
    }
    
    /**
     * 获取指定学生的最大点名次数
     * @param studentName 学生姓名
     * @return 最大点名次数，如果未单独设置则返回默认值
     */
    public int getStudentMaxCallTimes(String studentName) {
        return studentMaxCallTimes.getOrDefault(studentName, maxCallTimes);
    }
    
    /**
     * 随机点名方法
     *  返回被点到的学生信息，格式为"小组：姓名（第几次）"
     */
    public String randomCall() {
        if (studentMap.isEmpty()) {
            return "所有学生已被点过名达到最大次数。";
        }

        List<String> availableStudents = new ArrayList<>();
        for (String studentName : studentMap.keySet()) {
            int currentCount = studentCallCount.getOrDefault(studentName, 0);
            int maxTimes = studentMaxCallTimes.getOrDefault(studentName, maxCallTimes);
            if (currentCount < maxTimes) {
                availableStudents.add(studentName);
            }
        }
        
        if (availableStudents.isEmpty()) {
            return "所有学生已被点过名达到最大次数。";
        }

        int index = random.nextInt(availableStudents.size());
        String studentName = availableStudents.get(index);
        String group = studentMap.get(studentName);
        
        // 更新学生被点名次数
        int currentCount = studentCallCount.getOrDefault(studentName, 0) + 1;
        studentCallCount.put(studentName, currentCount);
        
        // 如果达到最大次数，则从可用学生中移除
        if (currentCount >= maxCallTimes) {
            calledStudentsMap.put(studentName, group);
            studentMap.remove(studentName);
        }
        
        // 保存状态变化
        saveStateToFile();
        saveCallCountToFile();
        
        return group + "：" + studentName + "（第" + currentCount + "次）";
    }
    
    /**
     * 重新加载所有学生数据
     * 清空当前内存中的数据并重新从文件加载
     */
    public void reloadStudents() {
        calledStudentsMap.clear();
        studentMap.clear();
        studentCallCount.clear();
        initialize();
        saveCallCountToFile();
    }
    
    /**
     * 获取当前未点名学生的映射关系
     */
    public Map<String, String> getStudentMap() {
        return studentMap;
    }
    
    // 保存状态到文件
    private void saveStateToFile() {
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(SAVE_FILE_PATH))) {
            oos.writeObject(new HashMap<>(studentMap));
            oos.writeObject(new HashMap<>(calledStudentsMap));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 从文件加载状态
    @SuppressWarnings("unchecked")
    private void loadStateFromFile() {
        File file = new File(SAVE_FILE_PATH);
        if (!file.exists()) {
            return;
        }
        
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(SAVE_FILE_PATH))) {
            studentMap = (Map<String, String>) ois.readObject();
            calledStudentsMap = (Map<String, String>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    // 添加保存点名次数的方法
    private void saveCallCountToFile() {
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(CALL_COUNT_FILE_PATH))) {
            oos.writeObject(maxCallTimes);
            oos.writeObject(new HashMap<>(studentCallCount));
            oos.writeObject(new HashMap<>(studentMaxCallTimes));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // 添加加载点名次数的方法
    @SuppressWarnings("unchecked")
    private void loadCallCountFromFile() {
        File file = new File(CALL_COUNT_FILE_PATH);
        if (!file.exists()) {
            return;
        }
        
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(CALL_COUNT_FILE_PATH))) {
            maxCallTimes = (Integer) ois.readObject();
            studentCallCount = (Map<String, Integer>) ois.readObject();
            studentMaxCallTimes = (Map<String, Integer>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    // 获取学生被点名次数的方法
    public Map<String, Integer> getStudentCallCount() {
        return studentCallCount;
    }
}